package com.xiaoyi.springboot.config.rabbitmq;


import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.Connection;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
 * rabbitmq配置
 * @author xiaoyi
 * @date 2021/10/10 22:31
 * @version v1.0
 */
@Configuration
@ConditionalOnProperty(
        name = {"spring.rabbitmq.enable"},
        havingValue = "true"
)
public class RabbitMqConfig {
    @Autowired
    private RabbitMqProperties properties;

    public RabbitMqConfig() {
    }

    @Bean
    @Primary
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setAddresses(this.properties.getAddresses());
        connectionFactory.setUsername(this.properties.getUsername());
        connectionFactory.setPassword(this.properties.getPassword());
        connectionFactory.setVirtualHost(this.properties.getVirtualHost());
        connectionFactory.setPublisherConfirms(this.properties.isPublisherConfirms());
        connectionFactory.setPublisherReturns(this.properties.isPublisherReturns());
        return connectionFactory;
    }

    @Bean
    @Primary
    public RabbitTemplate rabbitTemplate() {
        return new RabbitTemplate(this.connectionFactory());
    }
    // 初始化连接
    @Bean
    public Connection connection() {
        RabbitTemplate template = this.rabbitTemplate();
        return template.getConnectionFactory().createConnection();
    }
    // 初始化交换机
    @Bean
    public List<TopicExchange> first() {
        List<RabbitMqProperties.TemplateBinding> bindings = this.properties.getTemplateBindings();
        List<TopicExchange> list = Lists.newArrayList();
        if (CollectionUtils.isEmpty(bindings)) {
            return list;
        } else {
            TopicExchange topicExchange = null;
            Iterator iterator = bindings.iterator();

            while(iterator.hasNext()) {
                RabbitMqProperties.TemplateBinding s = (RabbitMqProperties.TemplateBinding)iterator.next();
                topicExchange = new TopicExchange(s.getExchange(), this.properties.isDurable(), this.properties.isAutoDelete());
                list.add(topicExchange);
            }

            return list;
        }
    }
    // 初始化队列
    @Bean
    public List<Queue> second() {
        List<RabbitMqProperties.TemplateBinding> bindings = this.properties.getTemplateBindings();
        List<Queue> list = Lists.newArrayList();
        if (CollectionUtils.isEmpty(bindings)) {
            return list;
        } else {
            Queue queue = null;
            Iterator iterator = bindings.iterator();

            while(iterator.hasNext()) {
                RabbitMqProperties.TemplateBinding s = (RabbitMqProperties.TemplateBinding)iterator.next();
                queue = new Queue(s.getQueue(), this.properties.isDurable());
                list.add(queue);
            }

            return list;
        }
    }
    // 交换机绑定队列通过特殊的key
    @Bean
    public List<Binding> third() {
        List<RabbitMqProperties.TemplateBinding> bindings = this.properties.getTemplateBindings();
        List<Binding> list = Lists.newArrayList();
        if (CollectionUtils.isEmpty(bindings)) {
            return list;
        } else {
            List<TopicExchange> exchanges = this.first();
            List<Queue> queues = this.second();
            if (!CollectionUtils.isEmpty(exchanges) && !CollectionUtils.isEmpty(queues)) {
                Map<String, TopicExchange> exMap = Maps.newHashMap();
                Map<String, Queue> queMap = Maps.newHashMap();
                Iterator binding = exchanges.iterator();

                while(binding.hasNext()) {
                    TopicExchange temp = (TopicExchange)binding.next();
                    exMap.put(temp.getName(), temp);
                }

                binding = queues.iterator();

                while(binding.hasNext()) {
                    Queue temp = (Queue)binding.next();
                    queMap.put(temp.getName(), temp);
                }

                binding = null;
                Iterator iterator = bindings.iterator();

                while(iterator.hasNext()) {
                    RabbitMqProperties.TemplateBinding s = (RabbitMqProperties.TemplateBinding)iterator.next();
                    Binding binding1 = BindingBuilder.bind((Queue)queMap.get(s.getQueue())).to((TopicExchange)exMap.get(s.getExchange())).with(s.getRouteKey());
                    list.add(binding1);
                }

                return list;
            } else {
                return list;
            }
        }
    }
}
